编译 Android 按键映射分析
更新日期:
android 能够将不同的低层 scancode 转化成上层使用的统一的 keycode (以下分析为 android 2.2 froyo 的)。下面说的几个相关的源代码文件都在 framework/base/libs/ui 下。
EventHub.cpp
先看看下面这段代码:
|
|
这段代码是打开键盘设备,并读取按键映射表的。从代码里可以看得到映射文件是从 root/usr/keylayout/qwerty.kl (root 一般是 system)下读取的(这个 qwerty.kl 各个设备厂商应该可以自己改,我看的 x86 的默认使用的是这个)。
kl 文件
这个文件就是 android 的按键映射文件,结构如下:
BACK:
- BEGIN: key
- SCANCODE: 1
- KEYCODE: BACK
- FLAG: WACK_DROPPED
POWER:
- BEGIN: key
- SCANCODE: 116
- KEYCODE: POWER
- FLAG: WACK
这里配合看下下面的代码,在 KeyLayoutMap.cpp 里:
|
|
可以看得出,android 会解析 kl 文件里的项目,然后把解析后的结果保存到一个 Vector 结构里(android 自己写一个 vector,不是 c++ std 的)。 kl 文件的每一项分为4段:
BEGIN
这一段统一是 “key”,应该是按键映射的标识。SCANCODE
这一段直接将字符串转化为数字,也就是说 kl 文件里的这一段存储的是数字。这里值就是从低层硬件读取出来值。也就是我们在 OM 项目中, vfb 应该发送给 android 的值。这个值不是 android sdk 中描述的值(这个值是上层应用使用的)。不同的硬件会不一样。KEYCODE
这个值就是 android sdk 里描述的啦。不过这一段有很多都是字符串,不是直接保存数值的,这个有个转化关系,具体的后面再说。FLAG
这里目前来说就2个值 WAKE 和 WAKE_DROPPED 。好像 WAKE 代表可以在锁机状态下唤醒屏幕。
KeycodeLabels.h
上面说了 KEYCODE 那里很多是保存字符串的,那么转化的地方就在这个文件里(这个文件在 framework/base/include/ui 下):
|
|
前面说的那个 load 代码里 KEYCODE 那一段的 keycode = token_to_value(token.string(), KEYCODES); 中的 token_to_value 就是通过上面这个数组来得到对应的数值的。这个数值就是 android sdk 里写的给上层应用程序使用的按键值了。所以一般来说,我们修改 kl 文件就可以改变按键映射了。